#include "leveleditor.h"
#include "ui_leveleditor.h"
#include "simulationwindow.h"
#include "designwindow.h"
#include "mainwindow.h"
#include "userdata.h"
#include "projectexplorer.h"

#include "sk_level_item.h"
#include "sk_creation_params.h"
#include "sk_game_model.h"

#include <QGraphicsRectItem>
#include <QDebug>

#include "sk_game_level.h"
#include "sk_box_shape.h"
#include "sk_circle_shape.h"
#include "sk_triangle_shape.h"

#include <Box2D.h>

LevelEditor::LevelEditor(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::leveleditor)
{
    ui->setupUi(this);

    ui->wgtDesign->setLayout(ui->layoutDesign);
    ui->wgtSimulation->setLayout(ui->layoutSimulation);

    ui->tabWidget->removeTab(0);
    ui->tabWidget->removeTab(0);

    _UD.dw = new DesignWindow(this);

    ui->tabWidget->addTab(_UD.dw, tr("Design"));
    ui->tabWidget->addTab(new SimulationWindow(this), tr("Simulation"));

    setLayout(ui->mainLayout);

    on_tabWidget_currentChanged(0);
    _levelItem = 0;
    _first = true;
    setLevelItem(0);
    _UD.le = this;
}

void LevelEditor::setDesign() const
{
    ui->tabWidget->setCurrentIndex(0);
}

void LevelEditor::createEditableObjects()
{
   if (0 == designWindow()->scene())
   {
       return;
   }
   designWindow()->scene()->clear();
   if (0 == _levelItem)
   {
       return;
   }
   // todo : think of how to do this in a brilliant way
   sk::GameLevel * l = _levelItem->level();
   designWindow()->scene()->addItem(new QGraphicsRectItem(0, 0, l->w, l->h));
   sk::GameItem * pr = _levelItem->child(0);
   for (int i = 0; i < l->shapes.size(); ++i)
   {
       sk::GameItem * it = pr->child(i);
       designWindow()->updateScene(it, false);
   }
   pr = _levelItem->child(1);
   for (int i = 0; i < l->dropShapes.size(); ++i)
   {
       sk::GameItem * it = pr->child(i);
       designWindow()->updateScene(it, true);
   }
}

void LevelEditor::setLevelItem(sk::LevelItem * item)
{	

    if (_levelItem == item && !_first)
    {
        return;
    }
    _first = false;
    if (_levelItem)
    {
        _levelItem->performForChilds(sk::OP_RESET_SCENE_ITEM);
    }
    _levelItem = item;
    ui->tabWidget->setEnabled(_levelItem != 0);
    ui->wgtDesign->setEnabled(_levelItem != 0);
    ui->wgtSimulation->setEnabled(_levelItem != 0);
    createEditableObjects();
}

LevelEditor::~LevelEditor()
{
    _UD.le = 0;
    _UD.dw = 0;
    delete ui;
}

void LevelEditor::on_tabWidget_currentChanged(int index)
{
    if (0 == index && _UD.sw)
    {
        _UD.sw->stop();
    }
    ui->wgtDesign->setVisible(0 == index);
    ui->wgtSimulation->setVisible(0 != index);
}

DesignWindow * LevelEditor::designWindow()
{
    return static_cast<DesignWindow *>(ui->tabWidget->widget(0));
}

void LevelEditor::on_btnCreateBox_clicked()
{
    sk::SimpleItemParam p;
    p.type = sk::IT_SIMPLE_BOX;
    p.drop = ui->chbDrop->isChecked();
    sk::SimpleBoxParam bp;
    bp.w = bp.h = 30;
    p.param = &bp;
    _doCreateItem(&p);
}

void LevelEditor::on_btnCreateCircle_clicked()
{
    sk::SimpleItemParam p;
    p.type = sk::IT_SIMPLE_CIRCLE;
    p.drop = ui->chbDrop->isChecked();
    sk::SimpleCircleParam bp;
    bp.r = 30;
    p.param = &bp;
    _doCreateItem(&p);
}

void LevelEditor::on_btnCreateTriangle_clicked()
{
    sk::SimpleItemParam p;
    p.type = sk::IT_SIMPLE_TRIANGLE;
    p.drop = ui->chbDrop->isChecked();
    sk::SimpleTriangleParam bp;
    bp.dx0 = 0;
    bp.dy0 = -50;
    bp.dx1 = 50;
    bp.dy1 = 0;
    p.param = &bp;
    _doCreateItem(&p);
}

bool LevelEditor::isDrop() const
{
    return ui->chbDrop->isChecked();
}

void LevelEditor::_doCreateItem(void * param)
{
    sk::GameItem * item = _UD.mw->model()->create(_levelItem, param);
    if (0 == item)
    {
        return;
    }

    designWindow()->updateScene(item, ui->chbDrop->isChecked());
    _UD.pe->activate(item);
}


void LevelEditor::on_btnStartSimulation_clicked()
{
    _UD.sw->start(_levelItem->index(), ui->chbGame->isChecked());
}

void LevelEditor::on_btnStopSimulation_clicked()
{
    _UD.sw->stop();
}
